package com.jiang.annotation.aop.log_exec;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 需要在启动类上添加 @EnableAspectJAutoProxy 注解
 */
@Aspect
@Component
@Slf4j
public class LogExecAspect {

    @Autowired
    private ApplicationContext context;

    @Around("@annotation(logExecution)")
    public Object logExecution(ProceedingJoinPoint joinPoint, LogExecution logExecution) throws Throwable {

        try {
            // 实例化 entity 对象
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            String[] parameterNames = methodSignature.getParameterNames();
            Object[] values = joinPoint.getArgs();
            Object entityObj = logExecution.entityClass().newInstance();
            for (int i = 0; i < parameterNames.length; i++) {
                Field field = entityObj.getClass().getDeclaredField(parameterNames[i]);
                field.setAccessible(true);
                field.set(entityObj, values[i]);
            }

            //获取 Service 对象
            Object serviceObj = context.getBean(logExecution.ServiceClass());

            //获取执行的 Method 对象，并执行
            Method method = serviceObj.getClass().getMethod(logExecution.method(), logExecution.entityClass());
            method.invoke(serviceObj, entityObj);
            return joinPoint.proceed();
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }
}
